package com.doeis.minaserver.module;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.doeis.common.utils.PasswordUtils;
import com.doeis.common.utils.StringUtils;
import com.doeis.log.QueueManager;
import com.doeis.minaserver.NettyServer;
import com.doeis.minaserver.bean.UserBasic;
import com.doeis.minaserver.container.BasicModule;
import com.doeis.minaserver.dao.User;
import com.doeis.minaserver.dao.UserDao;
import com.doeis.minaserver.packet.InfoPacket;
import com.doeis.minaserver.packet.Packet;
import com.doeis.minaserver.packet.Packet.PacketType;
import com.doeis.minaserver.packet.ServerPacketFactory;
import com.doeis.minaserver.session.ClientConnection;
import com.doeis.push.BaiduServiceContext;
import com.doeis.push.PushBaidu;
import com.doeis.uwork.bean.ItemAttrs;
import com.doeis.uwork.common.Constant;
import com.doeis.uwork.common.PacketUtil;
import com.doeis.uwork.dao.ItemDao;
import com.doeis.uwork.dao.OffPacketMongoDao;
import com.doeis.uwork.dao.ShareDao;
import com.doeis.uwork.entity.Item;
import com.doeis.uwork.entity.ItemNoteComment;
import com.doeis.uwork.entity.ItemNotes;
import com.doeis.uwork.entity.Share;
import com.doeis.uwork.entity.mongo.GroupMsg;
import com.doeis.uwork.entity.mongo.OffPacket;
import com.doeis.uwork.packet.GroupMsgPacket;
import com.voland.core.db.DBManager;

/**
 * 用户控制信息
 * **/
public class UserManager extends BasicModule {

	private static final Logger log = Logger.getLogger(UserManager.class);
	
	private ClientConnectionManager connManager;
	
	private UserDao userDao;
	private OffPacketMongoDao offPacketMongoDao;
	private ShareDao shareDao;
	private ItemDao itemDao;
	
	public UserManager() {
		super(" User Manager ");
	}
	
	public UserManager(String moduleName) {
		super(moduleName);
	}

	@Override
	public void initialize(NettyServer server) {
		this.server = server;
		
		connManager = server.getClientConnectionManager();
		itemDao = server.getItemDao();
		userDao = server.getInjectorInstance(UserDao.class);
		offPacketMongoDao = server.getInjectorInstance(OffPacketMongoDao.class);
		shareDao = server.getInjectorInstance(ShareDao.class);
	}
	
	@Override
	public void start() {
		
	}

	/**
	 * 用户登录
	 * @param clientConn
	 * @param p
	 */
	public void loginAction(ClientConnection clientConn, InfoPacket p) {
		UserBasic userBasic = p.decoder(UserBasic.class);
		QueueManager queueManager = server.getT(QueueManager.class);
		
		try{
			if (StringUtils.isBlank(userBasic.getLogin()) || StringUtils.isBlank(userBasic.getPwd())) {
				sendLoginErrorTip(clientConn, userBasic.getLogin(), 
							"用户名与密码不能为空" );
				 return ;
			}
			
			String loginid = userBasic.getLogin();
			User u = userDao.findUserForLogin(loginid, false);
			if(u==null){
				sendLoginErrorTip(clientConn, userBasic.getLogin(), 
						 "用户'" + userBasic.getLogin() + "'不存在" );
				 return ;
			}		
			
			//查看是否激活了
			if(!Boolean.TRUE.equals(u.getStatus())){
				sendLoginErrorTip(clientConn, userBasic.getLogin(), 
						 "用户'" + u.getName() + "'未激活，无法登陆"  );
				 return ;
			}
			
			String encrypt_pwd = PasswordUtils.encrypt(userBasic.getPwd(), u.getSalt());		
			if(u.getPwd()==null || !u.getPwd().equals(encrypt_pwd)){
				sendLoginErrorTip(clientConn, userBasic.getLogin(), 
						 "用户'" + u.getName() + "',密码错误" );
				 return ;
			}
			
			clientConn.setUserid(u.getId());
			clientConn.setSwitchboard_id(u.getSwitchboard_id());
			clientConn.setStatus(ClientConnection.STATUS_LOGIN);
			clientConn.setRegistrationID(userBasic.getRegistrationID());
			connManager.changeConnectionToAuth(clientConn);
			
			if(queueManager!=null){
				queueManager.sendLog(clientConn.getChannelHandlerContext(), Constant.SESSION_STATUS_LOGIN);
			}
			
			userBasic.setUserid(u.getId());
			p.setBodyObj(userBasic);
			
			InfoPacket reply = ServerPacketFactory.replyUserLogin(p);
			reply.setNotifyType(InfoPacket.NT_USER_LOGIN_OK);
			clientConn.deliver(reply);
			
			//第二套离线消息处理
			//开始推送离线的消息
			List<OffPacket> listOffPackets = offPacketMongoDao.findOffPacket(u.getSwitchboard_id(), u.getId());
			
			List<OffPacket> listitemNote = new ArrayList<OffPacket>();
			List<OffPacket> listitemComment= new ArrayList<OffPacket>();
			List<OffPacket> listitemPraise= new ArrayList<OffPacket>();
			
			if(listOffPackets!=null){
				Map<String, OffPacket >  group_shareid_msg = new HashMap<String, OffPacket>();
				Map<String, Integer >  group_shareid_count = new HashMap<String, Integer>();
				
				for(OffPacket offPacket : listOffPackets){
					try{
						if(PacketType.groupMsg.ordinal() ==  offPacket.getPacketType()  ){//聊天消息
							if(offPacket.getCmd() == GroupMsgPacket.CMD_ITEM_NOTE){
								listitemNote.add(offPacket);
								offPacketMongoDao.delete(u.getSwitchboard_id(), offPacket);
								continue;
							}else if(offPacket.getCmd() == GroupMsgPacket.CMD_ITEM_NOTE_COMMENT){
								listitemComment.add(offPacket);
								offPacketMongoDao.delete(u.getSwitchboard_id(), offPacket);
								continue;
							}else if(offPacket.getCmd() == GroupMsgPacket.CMD_ITEM_NOTE_PRAISE){
								listitemPraise.add(offPacket);
								offPacketMongoDao.delete(u.getSwitchboard_id(), offPacket);
								continue;
							}
							
							try{
								GroupMsg groupMsg = JSON.parseObject(offPacket.getBody(), GroupMsg.class);
								Integer count = group_shareid_count.get(groupMsg.getShareid());
								if(count==null){
									group_shareid_count.put(groupMsg.getShareid(), 1);
								}else{
									group_shareid_count.put(groupMsg.getShareid(), count+1);
								}
								group_shareid_msg.put(groupMsg.getShareid(), offPacket);
							}catch(Exception e){
								
							}finally{
								offPacketMongoDao.delete(u.getSwitchboard_id(), offPacket);
							}
						}
					}catch(Exception e){
						e.printStackTrace();
					}
				}
				
				for(String shareid : group_shareid_msg.keySet() ){
					OffPacket offPacket = group_shareid_msg.get(shareid);
					Packet packet = PacketUtil.clonePacket(offPacket);
					packet.setCmd(GroupMsgPacket.NOTIFY_MSG_ADD_OTHER_OFF);
					GroupMsg groupMsg = JSON.parseObject(packet.getBody(), GroupMsg.class);
					Share share = shareDao.findShareByid(shareid);
					if(share!=null){
						groupMsg.setGroup_avatar(share.getHead_pic());
					}
					groupMsg.setToUser(null);
					groupMsg.setCount(group_shareid_count.get(shareid));
					packet.setBody(JSON.toJSONString(groupMsg));
					clientConn.deliver(packet);
				}
			}
			
			//心得列表发送
			ItemNotes itemNotes = null;
			List<ItemNotes> sendItemNotes = new ArrayList<ItemNotes>();
			//开始向客户端推送消息
			for(int i=0; i<listitemNote.size() ;i++ ){
				itemNotes = JSON.parseObject( listitemNote.get(i).getBody(), ItemNotes.class);
				
				Item item = itemDao.findItemByid(itemNotes.getItem_id());
				if(item!=null){
					String text_itemString = null;
					if(Constant.DATA_SOURCE_SHARE.equals(item.getData_source())){
						Item original_item = itemDao.findItemByid(item.getOriginal_item_id());
						text_itemString = original_item.getAttrs();
					}else{
						text_itemString = item.getAttrs();
					}
					
					if(!StringUtils.isBlank(text_itemString)){
						try {
							ItemAttrs itemAttrs = JSON.parseObject(text_itemString, ItemAttrs.class);
							itemNotes.setTextItem(itemAttrs.isTextItem());
						} catch (Exception e) {
						}
					}
					
				}
				
				sendItemNotes.add(itemNotes);
				if(i>0 && i%50==0){
					Packet packet = PacketUtil.clonePacket(listitemNote.get(i));
					packet.setBody(JSON.toJSONString(sendItemNotes));
					packet.setCmd(GroupMsgPacket.CMD_ITEM_NOTE_LIST);
					clientConn.deliver(packet);
					sendItemNotes.clear();
				}
			}
			
			if(sendItemNotes.size()>0){
				Packet packet = PacketUtil.clonePacket(listitemNote.get(0));
				packet.setBody(JSON.toJSONString(sendItemNotes));
				packet.setCmd(GroupMsgPacket.CMD_ITEM_NOTE_LIST);
				clientConn.deliver(packet);
				sendItemNotes.clear();
			}
			
			//心得点评列表发送
			ItemNoteComment itemNoteComment = null;
			List<ItemNoteComment> sendItemNoteComment = new ArrayList<ItemNoteComment>();
			//开始向客户端推送消息
			for(int i=0; i<listitemComment.size() ;i++ ){
				itemNoteComment = JSON.parseObject( listitemComment.get(i).getBody(), ItemNoteComment.class);
				sendItemNoteComment.add(itemNoteComment);
				if(i>0 && i%50==0){
					Packet packet = PacketUtil.clonePacket(listitemComment.get(i));
					packet.setBody(JSON.toJSONString(sendItemNoteComment));
					packet.setCmd(GroupMsgPacket.CMD_ITEM_NOTE_COMMENT_LIST);
					clientConn.deliver(packet);
					sendItemNoteComment.clear();
				}
			}
			
			if(sendItemNoteComment.size()>0){
				Packet packet = PacketUtil.clonePacket(listitemComment.get(0));
				packet.setBody(JSON.toJSONString(sendItemNoteComment));
				packet.setCmd(GroupMsgPacket.CMD_ITEM_NOTE_COMMENT_LIST);
				clientConn.deliver(packet);
				sendItemNoteComment.clear();
			}
			
			//心得点赞列表发送
			ItemNotes itemNotePraise = null;
			List<ItemNotes> sendItemNotePraise = new ArrayList<ItemNotes>();
			//开始向客户端推送消息
			for(int i=0; i<listitemPraise.size() ;i++ ){
				itemNotePraise = JSON.parseObject( listitemPraise.get(i).getBody(), ItemNotes.class);
				sendItemNotePraise.add(itemNotePraise);
				if(i>0 && i%50==0){
					Packet packet = PacketUtil.clonePacket(listitemPraise.get(i));
					packet.setBody(JSON.toJSONString(sendItemNotePraise));
					packet.setCmd(GroupMsgPacket.CMD_ITEM_NOTE_PRAISE_LIST);
					clientConn.deliver(packet);
					sendItemNotePraise.clear();
				}
			}
			
			if(sendItemNotePraise.size()>0){
				Packet packet = PacketUtil.clonePacket(listitemPraise.get(0));
				packet.setBody(JSON.toJSONString(sendItemNotePraise));
				packet.setCmd(GroupMsgPacket.CMD_ITEM_NOTE_PRAISE_LIST);
				clientConn.deliver(packet);
				sendItemNotePraise.clear();
			}
		}catch(Exception e){
			e.printStackTrace();
			log.error("查询用户", e.getCause());
		}finally{
			DBManager.closeBindConnection(DBManager.getDefaultDataSourceName(Boolean.TRUE.booleanValue()));
		}
	}

	/****百度推送信息****/
	public void baiduPush(ClientConnection clientConn, InfoPacket p) {
		PushBaidu pushBaidu = p.decoder(PushBaidu.class);
		BaiduServiceContext.putPushBaidu(pushBaidu);
		InfoPacket reply = ServerPacketFactory.replyPushoK(p);
		clientConn.deliver(reply);
	}

	
}
